---
title: 읽기 시간 추가
description: 마크다운 및 MDX 파일에 읽기 시간을 추가하기 위해 remark 플러그인을 구축합니다.
i18nReady: true
type: recipe
---

import PackageManagerTabs from '~/components/tabs/PackageManagerTabs.astro'

Markdown 또는 MDX 파일의 프런트매터에 읽기 시간 속성을 추가하는 [remark 플러그인](https://github.com/remarkjs/remark)을 만듭니다. 이 속성을 사용하여 각 페이지의 읽기 시간을 표시합니다.

## 레시피

1. 도우미 패키지 설치

  다음 두 개의 도우미 패키지를 설치하세요.
  - 읽은 시간 (분)을 계산하는 [`reading-time`](https://www.npmjs.com/package/reading-time)
  - Markdown에서 모든 텍스트를 추출하는 [`mdast-util-to-string`](https://www.npmjs.com/package/mdast-util-to-string)

  <PackageManagerTabs>
    <Fragment slot="npm">
    ```shell
  npm install reading-time mdast-util-to-string
    ```
    </Fragment>
    <Fragment slot="pnpm">
    ```shell
  pnpm add reading-time mdast-util-to-string
    ```
    </Fragment>
    <Fragment slot="yarn">
    ```shell
  yarn add reading-time mdast-util-to-string
    ```
    </Fragment>
  </PackageManagerTabs>

2. remark 플러그인 생성.

  이 플러그인은 `mdast-util-to-string` 패키지를 사용하여 Markdown 파일의 텍스트를 가져옵니다. 그런 다음 이 텍스트는 `reading-time` 패키지로 전달되어 읽기 시간 (분)을 계산합니다.

  ```js title="remark-reading-time.mjs"
  import getReadingTime from 'reading-time';
  import { toString } from 'mdast-util-to-string';

  export function remarkReadingTime() {
    return function (tree, { data }) {
      const textOnPage = toString(tree);
      const readingTime = getReadingTime(textOnPage);
      // readingTime.text는 친숙한 문자열로 읽은 시간을 제공합니다.
      // 예: "3 min read"
      data.astro.frontmatter.minutesRead = readingTime.text;
    };
  }
  ```

3. 구성에 플러그인을 추가하세요.

  ```js title="astro.config.mjs" "import { remarkReadingTime } from './remark-reading-time.mjs';" "remarkPlugins: [remarkReadingTime],"
  import { defineConfig } from 'astro/config';
  import { remarkReadingTime } from './remark-reading-time.mjs';

  export default defineConfig({
    markdown: {
      remarkPlugins: [remarkReadingTime],
    },
  });
  ```

  이제 모든 Markdown 문서의 프런트매터에는 계산된 `minutesRead` 속성이 있습니다.

4. 읽기 시간 표시

  만약 블로그 게시물이 [콘텐츠 컬렉션](/ko/guides/content-collections/)에 저장되어 있다면, `entry.render()` 함수의 `remarkPluginFrontmatter`에 액세스하세요. 그런 다음 템플릿에서 표시하려는 위치마다 `minutesRead`를 렌더링하세요.

  ```astro title="src/pages/posts/[slug].astro" "const { Content, remarkPluginFrontmatter } = await entry.render();" "<p>{remarkPluginFrontmatter.minutesRead}</p>"
  ---
  import { CollectionEntry, getCollection } from 'astro:content';

  export async function getStaticPaths() {
    const blog = await getCollection('blog');
    return blog.map(entry => ({
      params: { slug: entry.slug },
      props: { entry },
    }));
  }

  const { entry } = Astro.props;
  const { Content, remarkPluginFrontmatter } = await entry.render();
  ---

  <html>
    <head>...</head>
    <body>
      ...
      <p>{remarkPluginFrontmatter.minutesRead}</p>
      ...
    </body>
  </html>
  ```

  [Markdown 레이아웃](/ko/guides/markdown-content/#markdown-및-mdx-페이지)을 사용하는 경우 레이아웃 템플릿에서 `Astro.props`의 `minutesRead` frontmatter 속성을 사용하세요.

  ```astro title="src/layouts/BlogLayout.astro" "const { minutesRead } = Astro.props.frontmatter;" "<p>{minutesRead}</p>"
  ---
  const { minutesRead } = Astro.props.frontmatter;
  ---

  <html>
    <head>...</head>
    <body>
      <p>{minutesRead}</p>
      <slot />
    </body>
  </html>
  ```
